import { useState } from "react";
import Taro, { useRouter } from "@tarojs/taro";
import { PageContainer, Picker, Text, View } from "@tarojs/components";
import { useBoolean, useMap, useUnmount } from "ahooks";
import dayjs from "dayjs";

import ByRow from "@/components/ui/ByRow";
import ByCol from "@/components/ui/ByCol";
import ByCell from "@/components/ui/ByCell";
import ByIcon from "@/components/ui/ByIcon";
import Page from "@/components/common/Page";
import ByText from "@/components/ui/ByText";
import ByButton from "@/components/ui/ByButton";
import PopupMember from "@/components/app/PopupMember";
import { CartItem, CartItemOfMeasure } from "./components/CartMeasureSection";

import ApiBudget from "@/api/budget";
import useForm from "@/hooks/useForm";
import usePageEventChannel from "@/hooks/usePageEventChannel";

import { MaterialBudgetItem } from "@/types/budget";

const RenderSection = ({
  details,
  isMeasure,
  isOptional,
  onRemove,
}: {
  details: Set<MaterialBudgetItem>;
  isOptional: boolean;
  isMeasure: boolean;

  onRemove: (item) => void;
}) => {
  // 移除项
  const handleRemove = (target) => {
    details.delete(target);
    onRemove(details);
  };


  console.log("details", details)
  return [...details].map((item) => (
    <View className="mx-3 mt-3" key={item.materialCode}>
      {isMeasure ? (
        <CartItemOfMeasure
          source={item}
          key={item.materialId}
          onRemove={() => handleRemove(item)}
        />
      ) : (
        <CartItem
          source={item}
          key={item.materialId}
          isOptional={isOptional}
          onRemove={() => handleRemove(item)}
        />
      )}
    </View>
  ));
};

const rules = {
  details: {
    type: "array",
    defaultField: {
      type: "object",
      validator(rules, value, callback) {
        const index = +rules.field + 1;

        const {
          applyQuantity,
          materielCategory,
          requiredArrivalTime,
          requireMeasureDate,
        } = value;

        const isNotMeasure = materielCategory !== 6;

        if (!applyQuantity && isNotMeasure) {
          // 测量不检测这个
          callback(new Error(`第${index}项 未填写销售数量`));
        } else if (!requiredArrivalTime && !requireMeasureDate) {
          callback(new Error(`第${index}项 未选择到场时间`));
        } else {
          callback();
        }
      },
    },
  },
};

export default () => {
  const { params } = useRouter();
  const intentCustomerId = Number(params.intentCustomerId);

  // 提交表单
  const { loading, model, setModel, submit } = useForm(
    () =>
      ApiBudget[
      model.materielCategory === 6
        ? "saveMaterialMeasure"
        : "saveMaterialApplyEntity"
      ],
    {
      // @ts-expect-error
      rules,
      defaultModel: {
        intentCustomerId,
        materielCategory: 0,
        materielCategoryText: "",
        remindUserIds: [] as number[],
        // 本地使用
        remindUserNames: [] as string[],

        details: [] as MaterialBudgetItem[],
      },

      onSuccess(res) {
        Taro.showToast({ title: "提交成功！" });
        setTimeout(() => {
          const id = res.applyBillId;

          if (id) {
            Taro.redirectTo({ url: `detail?applyBillId=${id}` });
          } else {
            Taro.reLaunch({ url: `list?intentCustomerId=` + intentCustomerId });
          }
        }, 1500);
      },
    }
  );

  // 由前置页面传来的Map+Set结构数据（本页数据与前页数据是同步的）
  const [selectedMap, { get, set, setAll }] = useMap<
    number,
    Set<MaterialBudgetItem>
  >();
  const renderKeys = [...selectedMap.keys()];

  // 获取上级页面传的值
  const emit = usePageEventChannel<{
    map: typeof selectedMap;
    // details: MaterialBudgetItem[];
    materielCategory: number;
    materielCategoryText: string;
  }>("accpetBudgetDetails", ({ map, ...rest }) => {
    setAll(map);
    setModel(rest);

    // setModel({
    //   ...data,
    //   details: data.details.map((e) => ({
    //     ...e,
    //     intentCustomerId,
    //     materielCategory,
    //   })),
    // });
  });

  useUnmount(() => emit("updateCartOriginData", selectedMap));

  // 统一变更时间
  const [referenceTime, setReferenceTime] = useState<string>();
  const referenceRimeChange = async (e) => {
    const time = e.detail.value;

    const { confirm } = await Taro.showModal({
      title: `将材料到场时间统一设为${time}`,
    });

    if (confirm) {
      const property = isMeasure ? "requireMeasureDate" : "requiredArrivalTime";
      renderKeys.forEach((key) => {
        [...get(key)!].forEach((item) => {
          item[property] = time;
        });
      });
      setReferenceTime(time);
    }
  };

  // 选择提醒人
  const [visible, { setFalse, setTrue }] = useBoolean();

  // 弹窗状态改变
  const popupChange = (e) => {
    setModel({
      remindUserIds: e.map((e) => e.user_id),
      remindUserNames: e.map((e) => e.user_name),
    });

    setFalse();
  };

  const { materielCategory, remindUserNames } = model;
  // 是测量
  const isMeasure = materielCategory === 6;
  // 是自选
  const isOptional = materielCategory === 7;

  const handleSubmit = () => {
    const details = [...selectedMap.values()].reduce((ary, item) => {
      return [...ary, ...item.values()];
    }, [] as any[]);

    submit({ details });
  };

  return (
    <>
      <Page
        footerSticky
        slotFooter={
          <ByButton
            size="large"
            className="w-2/3"
            loading={loading}
            onClick={handleSubmit}
          >
            申报
          </ByButton>
        }
      >
        <View className="bg-white px-3">
          <ByCell label="申请单类型">{model.materielCategoryText}申请</ByCell>

          <ByRow>
            {!isMeasure && (
              <ByCol span={6}>
                <ByCell vertical label={"提醒人"} onClick={setTrue}>
                  {remindUserNames[0] || "-"}
                  {remindUserNames.length > 1 && (
                    <ByText size="sm" type="second">
                      等{remindUserNames.length}人
                    </ByText>
                  )}
                </ByCell>
              </ByCol>
            )}

            <ByCol span={6}>
              <Picker
                mode="date"
                value={referenceTime || ""}
                start={dayjs().format("YYYY-MM-DD")}
                onChange={referenceRimeChange}
              >
                <ByCell label="到场时间" vertical>
                  <View>
                    <Text>{referenceTime || "-"}</Text>
                    <ByIcon name="Calender" />
                  </View>
                </ByCell>
              </Picker>
            </ByCol>
          </ByRow>
        </View>

        {renderKeys.map(
          (key) =>
            !!get(key) && (
              <RenderSection
                key={key}
                details={get(key)!}
                isMeasure={isMeasure}
                isOptional={isOptional}
                onRemove={(details) => set(key, details)}
              />
            )
        )}
      </Page>

      <PageContainer round show={visible} onLeave={setFalse}>
        <PopupMember
          multiple
          type={["erp"]}
          title="选择提醒人"
          onCancel={setFalse}
          onConfirm={popupChange}
        />
      </PageContainer>
    </>
  );
};
